package com.ruoyi.shop.brand.service.impl;

import java.util.List;
import java.util.stream.Collectors;
import java.util.concurrent.TimeUnit;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;

import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.shop.api.domain.CarInfo;
import com.ruoyi.shop.brand.service.ICarInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.shop.brand.mapper.CarInfoMapper;

import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * 用户车辆Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-24
 */
@Slf4j
@Service
public class CarInfoServiceImpl implements ICarInfoService
{
	private static final String CACHE_KEY = "car";  // 缓存key前缀
	private static final String CACHE_LIST_KEY = CACHE_KEY + ":list";  // 列表缓存key
	private static final String CACHE_ID_KEY = CACHE_KEY + ":id:";  // 单个对象缓存key
	private static final String VERSION_KEY = "car:version:";  // 版本号key前缀
	private static final long VERSION_EXPIRE_TIME = 24 * 60 * 60; // 版本号过期时间（24小时）

	@Resource
	private CarInfoMapper carInfoMapper;

	@Autowired
	private RedisService redisService;

	/**
	 * 生成新的版本号
	 */
	private String generateNewVersion() {
		return String.valueOf(System.currentTimeMillis());
	}

	/**
	 * 获取带版本号的缓存key
	 */
	private String getVersionedKey(String baseKey, String version) {
		return baseKey + ":" + version;
	}

	/**
	 * 查询用户车辆
	 *
	 * @param id 用户车辆主键
	 * @return 用户车辆
	 */
	@Override
	public CarInfo selectCarInfoById(Long id)
	{
		if (id == null) {
			return null;
		}
		
		String cacheKey = CACHE_ID_KEY + id;
		String versionKey = VERSION_KEY + id;
		
		try {
			// 获取当前版本号
			String currentVersion = redisService.getCacheObject(versionKey);
			CarInfo carInfo = null;
			
			if (currentVersion != null) {
				carInfo = redisService.getCacheObject(getVersionedKey(cacheKey, currentVersion));
				if (carInfo != null) {
					log.debug("从缓存获取车辆信息成功, id: {}", id);
					return carInfo;
				}
			}
			
			// 缓存未命中，查询数据库
			carInfo = carInfoMapper.selectCarInfoById(id);
			if (carInfo != null) {
				String newVersion = generateNewVersion();
				// 设置版本号，加入过期时间
				redisService.setCacheObject(versionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				// 设置缓存
				redisService.setCacheObject(getVersionedKey(cacheKey, newVersion), carInfo);
				
				// 异步清理旧版本缓存
				if (currentVersion != null && !currentVersion.equals(newVersion)) {
					redisService.deleteObject(getVersionedKey(cacheKey, currentVersion));
				}
				
				log.debug("更新车辆缓存成功, id: {}, newVersion: {}", id, newVersion);
			}
			
			return carInfo;
		} catch (Exception e) {
			log.error("查询车辆详情异常, id: {}", id, e);
			// 发生异常时，直接查询数据库
			return carInfoMapper.selectCarInfoById(id);
		}
	}

	/**
	 * 查询用户车辆列表
	 *
	 * @param carInfo 用户车辆
	 * @return 用户车辆
	 */
	@Override
	public List<CarInfo> selectCarInfoList(CarInfo carInfo)
	{
		String cacheKey = CACHE_LIST_KEY;
		String versionKey = VERSION_KEY + "list";
		
		if (carInfo != null && carInfo.getUid() != null) {
			cacheKey = CACHE_LIST_KEY + ":uid:" + carInfo.getUid();
			versionKey = VERSION_KEY + "user:" + carInfo.getUid();
		}
		
		try {
			String currentVersion = redisService.getCacheObject(versionKey);
			List<CarInfo> cacheList = null;
			
			if (currentVersion != null) {
				cacheList = redisService.getCacheList(getVersionedKey(cacheKey, currentVersion));
				if (!CollectionUtils.isEmpty(cacheList)) {
					log.debug("从缓存获取车辆列表成功");
					return cacheList;
				}
			}
			
			// 缓存未命中，查询数据库
			cacheList = carInfoMapper.selectCarInfoList(carInfo);
			if (!CollectionUtils.isEmpty(cacheList)) {
				// 处理默认车辆逻辑
				handleDefaultCar(cacheList, carInfo);
				
				String newVersion = generateNewVersion();
				// 更新版本号
				redisService.setCacheObject(versionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				// 更新列表缓存
				redisService.setCacheList(getVersionedKey(cacheKey, newVersion), cacheList);
				
				// 更新单个对象缓存
				updateIndividualCaches(cacheList, newVersion);
				
				// 异步清理旧版本缓存
				if (currentVersion != null && !currentVersion.equals(newVersion)) {
					cleanOldVersionCaches(cacheKey, currentVersion, cacheList);
				}
				
				log.debug("更新车辆列表缓存成功, newVersion: {}", newVersion);
			}
			
			return cacheList;
		} catch (Exception e) {
			log.error("查询车辆列表异常", e);
			// 发生异常时，直接查询数据库
			return carInfoMapper.selectCarInfoList(carInfo);
		}
	}

	/**
	 * 处理默认车辆逻辑
	 */
	private void handleDefaultCar(List<CarInfo> carList, CarInfo queryInfo) {
		boolean hasDefault = carList.stream()
			.anyMatch(car -> car.getIsDefault() != null && car.getIsDefault() == 1);
		
		if (!hasDefault && !carList.isEmpty()) {
			CarInfo firstCar = carList.get(0);
			firstCar.setIsDefault(1L);
			updateCarInfo(firstCar);
			// 更新列表中的数据
			firstCar = carInfoMapper.selectCarInfoById(firstCar.getId());
			if (firstCar != null) {
				carList.set(0, firstCar);
			}
		}
	}

	/**
	 * 更新单个对象的缓存
	 */
	private void updateIndividualCaches(List<CarInfo> carList, String newVersion) {
		for (CarInfo car : carList) {
			String carVersionKey = VERSION_KEY + car.getId();
			String carCacheKey = CACHE_ID_KEY + car.getId();
			redisService.setCacheObject(carVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
			redisService.setCacheObject(getVersionedKey(carCacheKey, newVersion), car);
		}
	}

	/**
	 * 清理旧版本缓存
	 */
	private void cleanOldVersionCaches(String baseKey, String oldVersion, List<CarInfo> carList) {
		redisService.deleteObject(getVersionedKey(baseKey, oldVersion));
		for (CarInfo car : carList) {
			redisService.deleteObject(getVersionedKey(CACHE_ID_KEY + car.getId(), oldVersion));
		}
	}

	/**
	 * 过滤列表数据
	 */
	private List<CarInfo> filterList(List<CarInfo> list, CarInfo carInfo) {
		if (CollectionUtils.isEmpty(list) || carInfo == null) {
			return list;
		}

		return list.stream()
			.filter(item -> {
				if (StringUtils.hasText(carInfo.getCarNum())) {
					if (!item.getCarNum().contains(carInfo.getCarNum())) {
						return false;
					}
				}
				if (StringUtils.hasText(carInfo.getType())) {
					if (!item.getType().contains(carInfo.getType())) {
						return false;
					}
				}
				return true;
			})
			.collect(Collectors.toList());
	}

	/**
	 * 新增用户车辆
	 *
	 * @param carInfo 用户车辆
	 * @return 结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int insertCarInfo(CarInfo carInfo) {
		try {
			if (carInfo == null || carInfo.getUid() == null) {
				throw new RuntimeException("车辆信息或用户ID不能为空");
			}
			
			// 查询用户现有车辆
			CarInfo query = new CarInfo();
			query.setUid(carInfo.getUid());
			List<CarInfo> existingCars = carInfoMapper.selectCarInfoList(query);
			
			// 如果是第一辆车，设为默认
			if (existingCars.isEmpty()) {
				carInfo.setIsDefault(1L);
			} else {
				carInfo.setIsDefault(0L);
			}
			
			int result = carInfoMapper.insertCarInfo(carInfo);
			if (result > 0) {
				// 生成新版本号
				String newVersion = generateNewVersion();
				
				// 更新用户相关的版本号
				String userVersionKey = VERSION_KEY + "user:" + carInfo.getUid();
				redisService.setCacheObject(userVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				
				// 更新全局列表版本号
				String globalVersionKey = VERSION_KEY + "list";
				redisService.setCacheObject(globalVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				
				// 设置新车辆的版本号和缓存
				String carVersionKey = VERSION_KEY + carInfo.getId();
				String carCacheKey = CACHE_ID_KEY + carInfo.getId();
				redisService.setCacheObject(carVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				redisService.setCacheObject(getVersionedKey(carCacheKey, newVersion), carInfo);
				
				// 更新列表缓存
				List<CarInfo> updatedList = carInfoMapper.selectCarInfoList(query);
				if (!CollectionUtils.isEmpty(updatedList)) {
					String listCacheKey = CACHE_LIST_KEY + ":uid:" + carInfo.getUid();
					redisService.setCacheList(getVersionedKey(listCacheKey, newVersion), updatedList);
				}
				
				log.info("新增车辆信息成功并更新缓存, id: {}, newVersion: {}", carInfo.getId(), newVersion);
			}
			return result;
		} catch (Exception e) {
			log.error("新增车辆信息失败", e);
			throw e;
		}
	}

	/**
	 * 修改用户车辆
	 *
	 * @param carInfo 用户车辆
	 * @return 结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int updateCarInfo(CarInfo carInfo) {
		try {
			if (carInfo == null || carInfo.getId() == null) {
				throw new RuntimeException("车辆信息或ID不能为空");
			}
			
			// 如果要设置为默认车辆
			if (carInfo.getIsDefault() != null && carInfo.getIsDefault() == 1L) {
				// 先将该用户的所有车辆设为非默认
				CarInfo updateInfo = new CarInfo();
				updateInfo.setUid(carInfo.getUid());
				updateInfo.setIsDefault(0L);
				carInfoMapper.updateDefaultByUid(updateInfo);
			}
			
			int result = carInfoMapper.updateCarInfo(carInfo);
			if (result > 0) {
				// 生成新版本号
				String newVersion = generateNewVersion();
				
				// 更新用户相关的版本号
				String userVersionKey = VERSION_KEY + "user:" + carInfo.getUid();
				redisService.setCacheObject(userVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				
				// 更新全局列表版本号
				String globalVersionKey = VERSION_KEY + "list";
				redisService.setCacheObject(globalVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				
				// 更新车辆缓存
				CarInfo updatedCar = carInfoMapper.selectCarInfoById(carInfo.getId());
				if (updatedCar != null) {
					String carVersionKey = VERSION_KEY + carInfo.getId();
					String carCacheKey = CACHE_ID_KEY + carInfo.getId();
					redisService.setCacheObject(carVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
					redisService.setCacheObject(getVersionedKey(carCacheKey, newVersion), updatedCar);
				}
				
				// 更新列表缓存
				CarInfo query = new CarInfo();
				query.setUid(carInfo.getUid());
				List<CarInfo> updatedList = carInfoMapper.selectCarInfoList(query);
				if (!CollectionUtils.isEmpty(updatedList)) {
					String listCacheKey = CACHE_LIST_KEY + ":uid:" + carInfo.getUid();
					redisService.setCacheList(getVersionedKey(listCacheKey, newVersion), updatedList);
				}
				
				log.info("修改车辆信息成功并更新缓存, id: {}, newVersion: {}", carInfo.getId(), newVersion);
			}
			return result;
		} catch (Exception e) {
			log.error("修改车辆信息失败", e);
			throw e;
		}
	}

	/**
	 * 删除用户车辆信息
	 *
	 * @param id 用户车辆主键
	 * @return 结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int deleteCarInfoById(Long id) {
		try {
			// 先获取车辆信息，以便后续更新缓存
			CarInfo carInfo = carInfoMapper.selectCarInfoById(id);
			if (carInfo == null) {
				return 0;
			}

			Long uid = carInfo.getUid();
			int result = carInfoMapper.deleteCarInfoById(id);
			
			if (result > 0) {
				// 生成新版本号
				String newVersion = generateNewVersion();
				
				// 1. 删除该车辆的所有相关缓存
				String carCacheKey = CACHE_ID_KEY + id;
				String carVersionKey = VERSION_KEY + id;
				redisService.deleteObject(carCacheKey);
				redisService.deleteObject(carVersionKey);
				
				// 2. 更新用户车辆列表的版本号和缓存
				String userVersionKey = VERSION_KEY + "user:" + uid;
				String userListKey = CACHE_LIST_KEY + ":uid:" + uid;
				redisService.setCacheObject(userVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				
				// 重新查询并缓存用户的车辆列表
				CarInfo query = new CarInfo();
				query.setUid(uid);
				List<CarInfo> updatedList = carInfoMapper.selectCarInfoList(query);
				if (!CollectionUtils.isEmpty(updatedList)) {
					// 处理默认车辆逻辑
					handleDefaultCar(updatedList, null);
					// 更新列表缓存
					redisService.setCacheList(getVersionedKey(userListKey, newVersion), updatedList);
				} else {
					// 如果用户没有车辆了，删除列表缓存
					redisService.deleteObject(userListKey);
				}
				
				// 3. 更新全局列表的版本号和缓存
				String globalVersionKey = VERSION_KEY + "list";
				String globalListKey = CACHE_LIST_KEY;
				redisService.setCacheObject(globalVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				
				// 重新查询并缓存全局车辆列表
				List<CarInfo> globalList = carInfoMapper.selectCarInfoList(new CarInfo());
				if (!CollectionUtils.isEmpty(globalList)) {
					redisService.setCacheList(getVersionedKey(globalListKey, newVersion), globalList);
				} else {
					redisService.deleteObject(globalListKey);
				}
				
				log.info("删除车辆信息成功并更新缓存, id: {}, uid: {}, newVersion: {}", id, uid, newVersion);
			}
			
			return result;
		} catch (Exception e) {
			log.error("删除车辆信息失败, id: {}", id, e);
			throw new RuntimeException("删除车辆信息失败", e);
		}
	}

	/**
	 * 批量删除用户车辆
	 *
	 * @param ids 需要删除的用户车辆主键数组
	 * @return 结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int deleteCarInfoByIds(Long[] ids) {
		try {
			if (ids == null || ids.length == 0) {
				return 0;
			}

			// 获取所有要删除的车辆信息
			Set<Long> uidSet = new HashSet<>();
			for (Long id : ids) {
				CarInfo carInfo = carInfoMapper.selectCarInfoById(id);
				if (carInfo != null) {
					uidSet.add(carInfo.getUid());
				}
			}

			int result = carInfoMapper.deleteCarInfoByIds(ids);
			
			if (result > 0) {
				// 生成新版本号
				String newVersion = generateNewVersion();
				
				// 1. 删除所有相关车辆的缓存
				for (Long id : ids) {
					String carCacheKey = CACHE_ID_KEY + id;
					String carVersionKey = VERSION_KEY + id;
					redisService.deleteObject(carCacheKey);
					redisService.deleteObject(carVersionKey);
				}
				
				// 2. 更新所有相关用户的车辆列表缓存
				for (Long uid : uidSet) {
					String userVersionKey = VERSION_KEY + "user:" + uid;
					String userListKey = CACHE_LIST_KEY + ":uid:" + uid;
					redisService.setCacheObject(userVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
					
					// 重新查询并缓存用户的车辆列表
					CarInfo query = new CarInfo();
					query.setUid(uid);
					List<CarInfo> updatedList = carInfoMapper.selectCarInfoList(query);
					if (!CollectionUtils.isEmpty(updatedList)) {
						// 处理默认车辆逻辑
						handleDefaultCar(updatedList, null);
						// 更新列表缓存
						redisService.setCacheList(getVersionedKey(userListKey, newVersion), updatedList);
					} else {
						redisService.deleteObject(userListKey);
					}
				}
				
				// 3. 更新全局列表缓存
				String globalVersionKey = VERSION_KEY + "list";
				String globalListKey = CACHE_LIST_KEY;
				redisService.setCacheObject(globalVersionKey, newVersion, VERSION_EXPIRE_TIME, TimeUnit.SECONDS);
				
				List<CarInfo> globalList = carInfoMapper.selectCarInfoList(new CarInfo());
				if (!CollectionUtils.isEmpty(globalList)) {
					redisService.setCacheList(getVersionedKey(globalListKey, newVersion), globalList);
				} else {
					redisService.deleteObject(globalListKey);
				}
				
				log.info("批量删除车辆信息成功并更新缓存, ids: {}, newVersion: {}", Arrays.toString(ids), newVersion);
			}
			
			return result;
		} catch (Exception e) {
			log.error("批量删除车辆信息失败, ids: {}", Arrays.toString(ids), e);
			throw new RuntimeException("批量删除车辆信息失败", e);
		}
	}

	/**
	 * 更新用户所有车辆的默认状态
	 * 
	 * @param carInfo 包含用户ID和默认状态的对象
	 * @return 更新结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int updateDefaultByUid(CarInfo carInfo) {
		try {
			if (carInfo == null || carInfo.getUid() == null) {
				throw new RuntimeException("用户ID不能为空");
			}
			
			int result = carInfoMapper.updateDefaultByUid(carInfo);
			if (result > 0) {
				// 清除该用户的所有相关缓存
				clearCache(carInfo.getUid());
				
				// 重新加载该用户的车辆列表到缓存
				CarInfo query = new CarInfo();
				query.setUid(carInfo.getUid());
				List<CarInfo> updatedList = carInfoMapper.selectCarInfoList(query);
				if (!CollectionUtils.isEmpty(updatedList)) {
					String cacheKey = CACHE_LIST_KEY + ":uid:" + carInfo.getUid();
					redisService.setCacheList(cacheKey, updatedList);
				}
			}
			return result;
		} catch (Exception e) {
			log.error("更新用户车辆默认状态失败", e);
			throw e;
		}
	}

	/**
	 * 清除用户相关的缓存
	 */
	private void clearCache(Long uid) {
		try {
			if (uid != null) {
				log.info("清除用户缓存, uid: {}", uid);
				
				// 生成新版本号
				String newVersion = String.valueOf(System.currentTimeMillis());
				
				// 更新用户相关的版本号
				String userVersionKey = VERSION_KEY + "user:" + uid;
				redisService.setCacheObject(userVersionKey, newVersion);
				
				// 更新全局列表版本号
				String globalVersionKey = VERSION_KEY + "list";
				redisService.setCacheObject(globalVersionKey, newVersion);
				
				// 查询并更新单个车辆的版本号
				CarInfo query = new CarInfo();
				query.setUid(uid);
				List<CarInfo> carList = carInfoMapper.selectCarInfoList(query);
				if (!CollectionUtils.isEmpty(carList)) {
					for (CarInfo car : carList) {
						String carVersionKey = VERSION_KEY + car.getId();
						redisService.setCacheObject(carVersionKey, newVersion);
					}
				}
				
				log.info("缓存版本号更新完成, uid: {}, newVersion: {}", uid, newVersion);
			}
		} catch (Exception e) {
			log.error("清除缓存失败, uid: {}", uid, e);
		}
	}
}
